<template>
  <view class="item-list">
    <view class="search-box">
      <view class="search-input">
        <text class="iconfont icon-sousuo"></text>
        <input type="text" v-model="searchKey" placeholder="搜索姓名/身份证号" @input="onSearch" />
        <text class="clear-btn" v-if="searchKey" @click="clearSearch">×</text>
      </view>
      <text v-if="searchKey && matchedCount > 0" class="search-count">
        找到 {{ matchedCount }} 个结果
      </text>
    </view>
    <uv-tabs :list="tabsList" lineWidth="30" lineHeight="3" :activeStyle="{
      color: '#0086FF',
      fontWeight: 'bold'
    }" :inactiveStyle="{
      color: '#666',
      transform: 'scale(0.9)'
    }" itemStyle="padding-left: 15px; padding-right: 15px; height: 34px;" @change="handleTabChange"></uv-tabs>
    <scroll-view class="student-list" scroll-y :scroll-into-view="scrollToId" :scroll-with-animation="true"
      @scroll="onScroll" refresher-enabled :refresher-triggered="isRefreshing" @refresherrefresh="onRefresh"
      @scrolltolower="onLoadMore">
      <view class="item-list-item" v-for="item in filteredList" :key="item.id" :id="'student-' + item.id"
        :class="{ 'highlight': isHighlighted(item) }">
        <view class="item-list-item-top">
          <view class="item-list-item-top-left">
            <image :src="item.avatar" mode="aspectFill"></image>
            <view class="user-info">
              <view class="name-id">
                <text class="nickname">{{ item.nickname }}</text>
                <view class="info-item id-number">
                  <text class="iconfont icon-shenfenzhenghao"></text>
                  <text>{{ item.identity }}</text>
                </view>
              </view>
              <view class="sub-info">
                <text class="team-name">班期: {{ item.teamName }}</text>
                <text class="divider">|</text>
                <text class="charge">负责人: {{ item.charge || '暂无' }}</text>
                <text class="divider">|</text>
                <view class="info-item phone-number" @tap="makePhoneCall(item.phone)">
                  <text class="iconfont icon-shouji"></text>
                  <text data-phone="true">{{ item.phone }}</text>
                </view>
              </view>
            </view>
          </view>
          
        </view>
        <view class="item-list-item-center">
          <template v-if="item.scoreModel">
            <view class="score-info">
              <view class="score-header">
                <text class="score-title">模拟成绩</text>
                <view class="exam-info">
                  <text class="exam-count">模拟次数: {{ item.scoreModel.examCount || 0 }}</text>
                  <text class="last-time">最后模拟: {{ parseTime(item.scoreModel.lastTime) || '--' }}</text>
                </view>
              </view>
              <view class="score-stats">
                <view class="score-item max-score">
                  <view class="score-icon">
                    <text class="iconfont icon-arrow-up"></text>
                  </view>
                  <view class="score-content">
                    <text class="score-label">最高分</text>
                    <text class="score-value">{{ item.scoreModel.maxScore || '--' }}</text>
                  </view>
                </view>
                <view class="score-item min-score">
                  <view class="score-icon">
                    <text class="iconfont icon-arrow-down"></text>
                  </view>
                  <view class="score-content">
                    <text class="score-label">最低分</text>
                    <text class="score-value">{{ item.scoreModel.minScore || '--' }}</text>
                  </view>
                </view>
              </view>
              <view class="score-list" v-if="item.scoreModel.listScore && item.scoreModel.listScore.length">
                <view class="list-header">
                  <text class="list-title">历史成绩</text>
                  <text class="list-count">共{{ item.scoreModel.listScore.length }}次</text>
                </view>
                <view class="score-tags">
                  <text class="score-tag" v-for="(score, index) in item.scoreModel.listScore" :key="index">{{ score }}</text>
                </view>
              </view>
            </view>
          </template>
          <view class="clock-info" v-else>
            <view class="training-time-item" v-for="(time, index) in item.times" :key="index">
              <view class="time-info">
                <text class="time-title">培训时间{{ index + 1 }}：</text>
                <text class="time-range">{{ parseTime(time.startTime, "{m}-{d} {h}:{i}") || '--' }} - {{ parseTime(time.endTime, "{m}-{d} {h}:{i}") || '--' }}</text>
                <view class="punch-status" :class="time.punch ? 'punched' : 'unpunched'">
                  <text class="iconfont" :class="time.punch ? 'icon-daka' : 'icon-weidakarizhi'"></text>
                  <text>{{ time.punch ? '已打卡' : '未打卡' }}</text>
                </view>
              </view>
              <view class="punch-time" v-if="time.punch">
                <text>打卡时间：{{ parseTime(time.punchModel.createDate, "{m}-{d} {h}:{i}") }}</text>
              </view>
            </view>
          </view>
       
          <view class="progress-box">
            <!-- <view>
              <view class="progress-header">
                <text>审核进度</text>
                <view class="progress-stats">
                  <text class="progress-value">{{ item.progress || 0 }}/{{ item.total || 4 }}</text>
                  <text class="percentage">{{ Math.round((item.progress || 0) / (item.total || 4) * 100) || 0 }}%</text>
                </view>
              </view>
              <uv-line-progress :percentage="Math.round((item.progress || 0) / (item.total || 4) * 100) || 0"
                :showText="false" height="8" activeColor="#0086FF" inactiveColor="#E5E8EF"></uv-line-progress>
            </view> -->
            <view class="progress-header">
              <text>培训进度</text>
            </view>
            <view v-if="item.itemStatusList && item.itemStatusList.length" class="training-progress-list">
              <view class="training-progress-row" v-for="row in Math.ceil(item.itemStatusList.length / 2)" :key="row">
                <view class="training-progress-item" v-for="(project, idx) in item.itemStatusList.slice((row-1)*2, row*2)" :key="idx">
                  <view class="project-title">{{ project.title }}</view>
                  <view class="status-capsule-row">
                    <text class="status-capsule" :class="getStatusClass(project.status)">{{ getStatusText(project.status) }}</text>
                  </view>
                </view>
              </view>
            </view>
          </view>
        </view>
        <view class="item-list-item-bottom" v-if="!item.scoreModel">
          <uv-button type="primary" @click="handleDetail(item)" :customStyle="{
            width: '160rpx',
            height: '64rpx',
            borderRadius: '32rpx',
            fontSize: '26rpx'
          }">查看详情</uv-button>
        </view>
      </view>
      <view class="load-more" v-if="hasMore">
        <uv-loading-icon v-if="isLoading"></uv-loading-icon>
        <text>{{ isLoading ? '加载中...' : '上拉加载更多' }}</text>
      </view>
      <view class="no-more" v-else>
        <text>没有更多数据了</text>
      </view>
    </scroll-view>
    <uv-popup ref="detailPopup" mode="bottom" round="10" closeable :closeOnClickOverlay="false"
      :customStyle="{ height: '85vh', overflow: 'hidden', backgroundColor: '#F7F6F9' }">
      <view class="detail-popup">
        <view class="popup-header">
          <text class="title">{{ projectData.title }}</text>
        </view>
        <scroll-view scroll-y class="popup-scroll" :style="{ height: 'calc(85vh - 90rpx)' }">
          <view class="popup-content">
            <view class="audit-card" v-for="(item, index) in projectData.chapterList" :key="index">
              <view class="popup-content-item">
                <view class="popup-content-item-top">
                  <text class="item-label">项目名称</text>
                  <text class="item-title">{{ index + 1 }}. {{ item.title }}</text>
                </view>
                <view class="popup-content-item-top">
                  <text class="item-label">培训老师</text>
                  <view class="teacher-list">
                    <view class="teacher-item" v-if="projectData.times?.[0]?.teachers && projectData.times?.[0]?.teachers.length" v-for="(teacher, tIndex) in projectData.times?.[0]?.teachers" :key="tIndex">
                      <image class="teacher-avatar" :src="teacher.avatar || 'https://img.qiananquang.com/minapp/avatar.png'" mode="aspectFill"></image>
                      <text class="teacher-name">{{ teacher.name }}</text>
                    </view>
                    <text v-else class="value">--</text>
                  </view>
                </view>

                <view class="popup-content-item-center">
                  <view class="popup-content-item-center-box">
                    <text>审核状态</text>
                    <text :class="getStatusClass(item.status)">{{ getStatusText(item.status) }}</text>
                  </view>
                  <view v-if="item.status == 2" class="popup-content-item-center-box reject-reason">
                    <text>拒绝理由</text>
                    <text class="reason-text">{{ item.remark || '无' }}</text>
                  </view>
                  <view v-if="item.status != 0" class="popup-content-item-center-box">
                    <text>审核人</text>
                    <view class="info-row">
                      <image :src="item.teacherAvatar" mode="aspectFill" class="avatar"></image>
                      <text>{{ item.teacherName || '--' }}</text>
                    </view>
                  </view>
                  <view v-if="item.status != 0" class="popup-content-item-center-box">
                    <text>审核时间</text>
                    <text>{{ parseTime(item.createDate) || '--' }}</text>
                  </view>
                </view>
                <view class="popup-content-item-footer">
                  <uv-button type="primary" size="small" @click="handleAudit(item)"
                    :class="{ 'btn-disabled': item.status === 1 }" :disabled="item.status === 1">
                    {{ item.checked ? '已审核' : '审核' }}
                  </uv-button>
                </view>
              </view>
            </view>
          </view>
        </scroll-view>
      </view>
    </uv-popup>
    <uv-popup ref="auditPopup" mode="bottom" round="10" closeable :closeOnClickOverlay="false"
      :customStyle="{ height: '50vh', backgroundColor: '#fff' }">
      <view class="audit-popup">
        <view class="audit-popup-header">
          <text class="title">审核信息</text>
        </view>
        <view class="audit-popup-content">
          <view class="audit-info">
            <view class="info-item">
              <text class="info-label">科目名称</text>
              <text class="info-value">{{ projectData.title || '--' }}</text>
            </view>
            <view class="info-item">
              <text class="info-label">项目名称</text>
              <text class="info-value">{{ chapterItem?.title || '--' }}</text>
            </view>
            <view class="info-item">
              <text class="info-label">培训老师</text>
              <view v-for="item in projectData.times?.[0]?.teachers">
                <text class="info-value">{{ item.name || '--' }},</text>
              </view>
            </view>
            <view class="info-item">
              <text class="info-label">学生姓名</text>
              <view class="info-value" style="display: flex; align-items: center;">
                <image :src="studentData?.avatar" mode="aspectFill" class="avatar"></image>
                <text>{{ studentData?.nickname || '--' }}</text>
              </view>
            </view>
            <view class="info-item">
              <text class="info-label">身份证号码</text>
              <text class="info-value">{{ studentData?.identity || '--' }}</text>
            </view>
          </view>
          <view class="divider"></view>
          <uv-form ref="auditForm" :model="auditForm" :rules="auditRules" labelWidth="140rpx">
            <uv-form-item label="审核结果" class="form-item">
              <uv-switch v-model="auditForm.status" activeColor="#0086FF" inactiveColor="#fb4736" :activeValue="1"
                :inactiveValue="2" @change="handleSwitchChange"></uv-switch>
              <text class="result-text" :style="{ color: auditForm.status === 1 ? '#0086FF' : '#fb4736' }">
                {{ auditForm.status === 1 ? '通过' : '拒绝' }}
              </text>
            </uv-form-item>
            <uv-form-item class="form-item" v-if="auditForm.status === 2">
              <text class="label">拒绝理由</text>
              <uv-textarea v-model="auditForm.remark" placeholder="请输入拒绝理由" :maxlength="200" height="160"></uv-textarea>
            </uv-form-item>
          </uv-form>
        </view>
        <view class="audit-popup-footer">
          <uv-button @click="cancelAudit">取消</uv-button>
          <uv-button type="primary" @click="submitAudit">确认</uv-button>
        </view>
      </view>
    </uv-popup>
    <view class="search-nav" v-if="searchKey && matchedItems.length > 1">
      <view class="nav-controls">
        <text class="nav-btn" @click="prevResult">上一个</text>
        <text class="result-count">{{ currentMatchIndex + 1 }}/{{ matchedItems.length }}</text>
        <text class="nav-btn" @click="nextResult">下一个</text>
      </view>
    </view>
  </view>
</template>

<script>
import { getTeamStudentList, getStudentChapterDetailList, checkedStudentProject } from '@/http/teacher.js'
import { parseTime } from '@/utils/tools';
import WebSocketClient from '@/utils/webSocket.js'
export default {
  data() {
    return {
      parseTime,
      teamList: [], // 班级学生列表
      projectData: {
        chapterList: []
      },
      studentData: {},
      chapterItem: {},
      query: {
        pageNum: 1,
        pageSize: 60, // 减小每页数量
        teamId: ''
      },
      auditForm: {
        status: 1, // 1-通过 2-拒绝
        remark: ''
      },
      auditRules: {
        remark: [{
          required: true,
          message: '请输入拒绝理由',
          trigger: ['blur'],
          type: 'string'
        }]
      },
      searchKey: '',
      scrollToId: '',
      originalList: [],
      matchedItems: [],
      currentMatchIndex: 0,
      scrollTop: 0,
      currentTab: 0,
      tabsList: [
        {
          name: '全部学生',
          type: 0,
          badge: {
            value: 0,
            type: 'primary'
          }
        },
        {
          name: '已打卡',
          type: 1,
          badge: {
            value: 0,
            type: 'success'
          }
        },
        {
          name: '未打卡',
          type: 2,
          badge: {
            value: 0,
            type: 'error'
          }
        },
        {
          name: '已培训',
          type: 3,
          badge: {
            value: 0,
            type: 'warning'
          }
        },
        {
          name: '未培训',
          type: 4,
          badge: {
            value: 0,
            type: 'error'
          }
        }
      ],
      isRefreshing: false, // 是否正在刷新
      isLoading: false, // 是否正在加载更多
      hasMore: true, // 是否还有更多数据
      total: 0, // 总数据量
      platform: '', // 添加平台标识
      scrollLeft: 0, // 添加横向滚动位置
    }
  },

  computed: {
    getPunchedCount() {
      return this.teamList.filter(item => item.punch).length
    },
    getTrainedCount() {
      return this.teamList.filter(item => item.progress === item.total).length
    },
    getUntrainedCount() {
      return this.teamList.filter(item => !item.progress).length
    },
    matchedCount() {
      return this.matchedItems.length
    },
    filteredList() {
      console.log(this.teamList, 'filteredList');
      switch (this.currentTab) {
        case 0:
          return this.teamList
        case 1:
          return this.teamList.filter(item => item.punch)
        case 2:
          return this.teamList.filter(item => !item.punch)
        case 3:
          return this.teamList.filter(item => item.progress === item.total)
        case 4:
          return this.teamList.filter(item => !item.progress)
        default:
          return this.teamList
      }
    }
  },
  methods: {
    async getTeamList(isLoadMore = false) {
      if (!isLoadMore) {
        this.query.pageNum = 1
      }

      try {
        this.isLoading = true
        getTeamStudentList(this.query).then(res => {
          const list = (res.data.list || []).map(item => ({
            ...item,
            progress: item.plan?.split('/')[0],
            total: item.plan?.split('/')[1],
            // 示例数据，实际应后端返回
          }))

          this.total = res.data.total
          this.hasMore = this.query.pageNum * this.query.pageSize < this.total

          if (isLoadMore) {
            this.teamList = [...this.teamList, ...list]
            this.originalList = [...this.originalList, ...list]
          } else {
            this.teamList = list
            this.originalList = list
          }
        }).finally(() => {
          this.isLoading = false
          this.isRefreshing = false
        })
      } catch (err) {
        uni.showToast({
          title: '获取数据失败',
          icon: 'none'
        })
        this.isLoading = false
        this.isRefreshing = false
      }
    },

    async getStudentDetail(studentId) {
      try {
        const res = await getStudentChapterDetailList({
          uid: this.studentData.id,
          chapterId: this.query.chapterId
        })
        this.projectData = {
          ...res.data,
          chapterList: res.data.chapterItems
        }
      } catch (err) {
        uni.showToast({
          title: '获取详情失败',
          icon: 'none'
        })
      }
    },

    async handleDetail(item) {
      console.log(item);
      if (!item.times || !item.times.every(time => time.punch === true)) {
        uni.showModal({
          title: '签到提示',
          content: '该学生未签到打卡,提醒学生签到打卡',
          showCancel: false,
          confirmText: '知道了',
          success: async ({ confirm, cancel }) => {
            this.studentData = item
            await this.getStudentDetail(item.id)
            this.$refs.detailPopup.open()
          }
        })
      } else {
        this.studentData = item
        await this.getStudentDetail(item.id)
        this.$refs.detailPopup.open()
      }

    },

    handleAudit(item) {
      this.chapterItem = item
      this.auditForm = {
        status: item.status == 0 ? 1 : item.status,
        remark: item.remark
      }
      console.log(item, this.chapterItem)
      if (item.status === 1) return
      this.$refs.auditPopup.open()
    },

    async submitAudit() {
      if (this.auditForm.status === 2) {
        try {
          await this.$refs.auditForm.validate()
        } catch (error) {
          return
        }
      }

      try {
        const params = {
          ...(this.chapterItem?.id ? { id: this.chapterItem.id } : {}),
          itemId: this.chapterItem.itemId,
          status: this.auditForm.status,
          remark: this.auditForm.remark,
          userId: this.studentData.id,
          chapterId: this.query.chapterId,
          teacherId: this.userinfo.id,
          teacherName: this.userinfo.nickname,
          teacherAvatar: this.userinfo.avatar,
          title: this.chapterItem.title,
          checked: true,
          teamId: this.query.teamId
        }

        await checkedStudentProject(params)
        uni.showToast({
          title: '审核成功',
          icon: 'success'
        })
        this.$refs.auditPopup.close()
        this.getTeamList()
        this.resetAuditForm()
        await this.getStudentDetail(this.studentData.id)
      } catch (err) {
        console.log(err, 'err');
        // uni.showToast({
        //   title: '审核失败',
        //   icon: 'none'
        // })
      }
    },

    getStatusClass(status) {
      switch (status) {
        case 0: return 'status-pending'
        case 1: return 'status-pass'  // 合格
        case 2: return 'status-reject' // 不合格
        default: return 'status-pending' // 未审核
      }
    },

    getStatusText(status) {
      switch (status) {
        case 0: return '未审核'
        case 1: return '合格'
        case 2: return '不合格'
        default: return '未审核'
      }
    },

    handleSwitchChange(value) {
      // 切换为通过时清空拒绝理由
      if (value === 1) {
        this.auditForm.remark = ''
      }
    },

    cancelAudit() {
      this.$refs.auditPopup.close()
      this.resetAuditForm()
    },

    resetAuditForm() {
      this.auditForm = {
        status: 1,
        remark: ''
      }
    },

    onSearch() {
      if (!this.searchKey) {
        this.teamList = [...this.originalList]
        this.scrollToId = ''
        this.matchedItems = []
        this.currentMatchIndex = 0
        return
      }

      const key = this.searchKey.toLowerCase()
      this.matchedItems = this.originalList.filter(item =>
        item.nickname.toLowerCase().includes(key) ||
        item.identity.toLowerCase().includes(key)
      )

      if (this.matchedItems.length > 0) {
        this.currentMatchIndex = 0
        this.scrollToId = 'student-' + this.matchedItems[0].id
      }
    },

    clearSearch() {
      this.searchKey = ''
      this.scrollToId = ''
      this.matchedItems = []
      this.currentMatchIndex = 0
      this.teamList = [...this.originalList]
    },

    isHighlighted(item) {
      return this.matchedItems.includes(item) &&
        this.matchedItems[this.currentMatchIndex]?.id === item.id
    },

    nextResult() {
      if (this.currentMatchIndex < this.matchedItems.length - 1) {
        this.currentMatchIndex++
        this.scrollToId = 'student-' + this.matchedItems[this.currentMatchIndex].id
      }
    },

    prevResult() {
      if (this.currentMatchIndex > 0) {
        this.currentMatchIndex--
        this.scrollToId = 'student-' + this.matchedItems[this.currentMatchIndex].id
      }
    },

    onScroll(e) {
      this.scrollTop = e.detail.scrollTop
    },

    handleTabChange(index) {
      this.currentTab = index
      this.scrollToTab(index)
      
      switch (index.type) {
        case 0:
          delete this.query.punch
          delete this.query.status
          break
        case 1:
          this.query.punch = true
          delete this.query.status
          break
        case 2:
          this.query.punch = false
          delete this.query.status
          break
        case 3:
          this.query.status = 1
          delete this.query.punch
          break
        case 4:
          this.query.status = 0
          delete this.query.punch
          break
        default:
          break
      }
      
      this.query.pageNum = 1
      this.getTeamList()
    },

    updateBadges() {
      // this.tabsList[0].badge.value = this.teamList.length
      // this.tabsList[1].badge.value = this.getPunchedCount
      // this.tabsList[2].badge.value = this.getUnpunchCount 
      // this.tabsList[3].badge.value = this.getTrainedCount
      // this.tabsList[4].badge.value = this.getUntrainedCount
    },

    async onRefresh() {
      if (this.isLoading) return
      this.isRefreshing = true
      await this.getTeamList()
    },

    async onLoadMore() {
      if (this.isLoading || !this.hasMore) return
      this.query.pageNum++
      await this.getTeamList(true)

    },

    initWebSocket() {
      console.log('initWebSocket');

      this.wsClient = new WebSocketClient({
        url: 'wss://batapi.qiananquang.com:8222',
        heartbeatInterval: 30000,
        maxReconnectAttempts: 5
      })

      this.wsClient.onTokenInvalid(() => {

        console.error('Token失效，断开连接')

        uni.removeStorageSync('token')

        // setTimeout(() => {
        // 	uni.redirectTo({
        // 		url: '/pages/login/login'
        // 	})
        // }, 1500)
      })

      this.wsClient.onOpen(() => {
        console.log('WebSocket已连接')
      })

      this.wsClient.onMessage((res) => {
        try {
          const data = JSON.parse(res.data)
          console.log(data, '监听消息');
          if (data?.code == 200) {
            if (data?.data?.type == 'punch') {
              console.log(data.data, '监听消息');
              this.$nextTick(() => {
                uni.showToast({
                  title: data.data.nickname + '学生打卡成功',
                  icon: 'none'
                })
                if (this.query.chapterId == data.data.chapterId) {
                  this.teamList.forEach(item => {
                    if (item.id == data.data.uid) {
                      item.punch = true
                    }
                  })
                }
                console.log(this.teamList, 'this.teamList');
                // this.$refs.lffBarrage.add({item:{nickname:'大橙子',courseName:'课程名称'}});
              })
            }
          }
        } catch (error) {
          console.error('解析消息失败:', error)
        }
      })

      this.wsClient.onError((error) => {
        console.error('WebSocket 错误:', error)
      })

      this.wsClient.onClose(() => {
        console.log('WebSocket 已关闭')
      })

      this.wsClient.connect()
    },

    getPlatform() {
      // #ifdef H5
      this.platform = 'h5'
      // #endif
      
      // #ifdef MP-WEIXIN
      this.platform = 'mp'
      // #endif
    },

    scrollToTab(index) {
      this.$nextTick(() => {
        const query = uni.createSelectorQuery()
        
        // 获取tab的位置信息
        query.select('.uv-tabs').boundingClientRect()
        query.select(`.uv-tabs__item-${index}`).boundingClientRect()
        
        query.exec(([tabsRect, itemRect]) => {
          if (!tabsRect || !itemRect) return
          
          const centerPosition = itemRect.left + itemRect.width / 2 - tabsRect.left
          const scrollCenter = tabsRect.width / 2
          let newScrollLeft = this.scrollLeft + (centerPosition - scrollCenter)
          
          // 确保不会出现负值
          newScrollLeft = Math.max(0, newScrollLeft)
          
          if (this.platform === 'h5') {
            // H5环境使用scrollTo
            const tabsWrapper = document.querySelector('.uv-tabs__wrapper')
            if (tabsWrapper) {
              tabsWrapper.scrollTo({
                left: newScrollLeft,
                behavior: 'smooth'
              })
            }
          } else {
            // 小程序环境使用scrollLeft
            this.scrollLeft = newScrollLeft
          }
        })
      })
    },

    makePhoneCall(phoneNumber) {
      if (!phoneNumber) return
      uni.showModal({
        title: '拨打电话',
        content: `是否拨打电话给${phoneNumber}？`,
        success: (res) => {
          if (res.confirm) {  
            uni.makePhoneCall({
              phoneNumber,
              success: () => {
                console.log('拨打电话成功')
              },
              fail: (err) => {
                console.log('拨打电话失败', err)
              }
            })
          }
        }
      })
    },
  },

  // 页面周期函数--监听页面加载
  onLoad(options) {
    this.getPlatform() // 获取平台类型
    this.userinfo = uni.getStorageSync('userinfo')
    this.query.teamId = options.teamId
    this.query.chapterId = options.chapterId
    uni.setNavigationBarTitle({
      title: options.title
    })
    
    // 如果有status参数，设置对应的tab
    if (options.status !== undefined) {
      const statusMap = {
        '0': 4, // 未培训
        '1': 3  // 已培训
      }
      const tabIndex = statusMap[options.status]
      if (tabIndex !== undefined) {
        this.currentTab = tabIndex
        // 等待DOM渲染完成后滚动
        setTimeout(() => {
          this.scrollToTab(tabIndex)
        }, 100)
      }
    }
    
    this.initWebSocket()
  },
  // 页面周期函数--监听页面初次渲染完成
  onReady() { },
  // 页面周期函数--监听页面显示(not-nvue)
  onShow() {
    this.getTeamList()
  },
  // 页面周期函数--监听页面隐藏
  onHide() {

  },
  // 页面周期函数--监听页面卸载
  onUnload() {
    if (this.wsClient) {
      this.wsClient.close()
      this.wsClient = null
    }
  },
  // 页面处理函数--监听用户下拉动作
  // onPullDownRefresh() { uni.stopPullDownRefresh(); },
  // 页面处理函数--监听用户上拉触底
  // onReachBottom() {},
  // 页面处理函数--监听页面滚动(not-nvue)
  // onPageScroll(event) {},
  // 页面处理函数--用户点击右上角分享
  // onShareAppMessage(options) {},

  watch: {
    teamList: {
      handler() {
        this.updateBadges()
      },
      immediate: true
    }
  }
}
</script>

<style lang="scss" scoped>
.item-list {
  padding: 16rpx;
  background: #F5F6F8;
  min-height: 100vh;

  &-item {
    background: #FFFFFF;
    border-radius: 12rpx;
    margin-bottom: 16rpx;
    overflow: hidden;
    box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);

    &-top {
      padding: 16rpx;
      background: #F8F9FC;
      display: flex;
      justify-content: space-between;
      align-items: center;

      &-left {
        display: flex;
        align-items: center;
        gap: 12rpx;

        image {
          width: 72rpx;
          height: 72rpx;
          border-radius: 36rpx;
          border: 2rpx solid #E5E8EF;
        }

        .user-info {
          .name-id {
            display: flex;
            align-items: center;
            gap: 16rpx;
            margin-bottom: 4rpx;

            .nickname {
              font-size: 28rpx;
              font-weight: 600;
              color: #333;
            }

            .id-number {
              font-size: 24rpx;
              color: #666;
              display: flex;
              align-items: center;
              gap: 4rpx;

              .iconfont {
                font-size: 24rpx;
                color: #999;
              }
            }
          }

          .sub-info {
            display: flex;
            align-items: center;
            gap: 8rpx;
            color: #666;
            font-size: 24rpx;

            .divider {
              color: #EBEDF0;
            }

            .phone-number {
              display: flex;
              align-items: center;
              gap: 4rpx;
              
              text[data-phone="true"] {
                color: #0086FF;
                text-decoration: underline;
              }

              .iconfont {
                font-size: 24rpx;
                color: #999;
              }
            }
          }
        }
      }
    }

    &-center {
      padding: 16rpx;

      .clock-info {
        margin-bottom: 16rpx;
        
        .training-time-item {
          background: #F8F9FC;
          border-radius: 8rpx;
          padding: 16rpx;
          margin-bottom: 12rpx;
          
          &:last-child {
            margin-bottom: 0;
          }

          .time-info {
            display: flex;
            align-items: center;
            gap: 8rpx;

            .time-title {
              font-size: 26rpx;
              font-weight: 500;
              color: #333;
              white-space: nowrap;
            }

            .time-range {
              flex: 1;
              font-size: 24rpx;
              color: #666;
            }

            .punch-status {
              display: flex;
              align-items: center;
              padding: 2rpx 12rpx;
              border-radius: 20rpx;
              font-size: 22rpx;
              white-space: nowrap;

              .iconfont {
                margin-right: 4rpx;
                font-size: 22rpx;
              }

              &.punched {
                background: #E8F7ED;
                color: #52C41A;
              }

              &.unpunched {
                background: #FFF3F0;
                color: #FF4D4F;
              }
            }
          }

          .punch-time {
            margin-top: 8rpx;
            padding-top: 8rpx;
            border-top: 2rpx solid rgba(0, 0, 0, 0.05);
            font-size: 22rpx;
            color: #666;
          }
        }
      }

      .progress-box {
        background: #F8F9FC;
        padding: 16rpx;
        border-radius: 8rpx;

        .progress-header {
          display: flex;
          justify-content: space-between;
          align-items: center;
          margin-bottom: 8rpx;

          text {
            font-size: 24rpx;
            color: #666;
          }
        }
      }
    }

    &-bottom {
      padding: 12rpx 16rpx;
      display: flex;
      justify-content: flex-end;
      border-top: 2rpx solid #F5F6F8;

      :deep(.uv-button) {
        min-width: 120rpx;
        height: 52rpx !important;
        line-height: 52rpx !important;
        font-size: 24rpx !important;
        padding: 0 20rpx !important;
      }
    }
  }
}

.detail-popup {
  height: 100%;
  display: flex;
  flex-direction: column;

  .popup-header {
    padding: 30rpx;
    display: flex;
    justify-content: space-between;
    align-items: center;
    border-bottom: 2rpx solid #eee;
    flex-shrink: 0;

    .title {
      font-size: 32rpx;
      font-weight: bold;
      color: #333;
    }

    .audit-btn {
      min-width: 120rpx;
    }
  }

  .popup-scroll {
    flex: 1;
    overflow: hidden;
  }

  .popup-content {
    padding: 30rpx;
    box-sizing: border-box;

    .audit-card {
      background: #fff;
      border-radius: 12rpx;
      padding: 24rpx;
      margin-bottom: 20rpx;
      box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);

      &:last-child {
        margin-bottom: 0;
      }
    }

    .popup-content-item-top {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 20rpx;

      .item-label {
        color: #666;
        font-size: 28rpx;
      }

      .teacher-list {
        flex: 1;
        display: flex;
        flex-wrap: wrap;
        gap: 16rpx;
        justify-content: flex-end;
        
        .teacher-item {
          display: flex;
          align-items: center;
          background: #F5F6F8;
          padding: 8rpx 16rpx;
          border-radius: 24rpx;
          
          .teacher-avatar {
            width: 32rpx;
            height: 32rpx;
            border-radius: 50%;
            margin-right: 8rpx;
          }
          
          .teacher-name {
            font-size: 24rpx;
            color: #333;
          }
        }

        .value {
          font-size: 26rpx;
          color: #999;
        }
      }
    }

    .popup-content-item-center {
      .popup-content-item-center-box {
        display: flex;
        justify-content: space-between;
        padding: 16rpx 0;
        border-bottom: 2rpx solid #f5f5f5;

        .info-row {
          display: flex;
          align-items: center;
          justify-content: space-between;
        }

        .avatar {
          width: 40rpx;
          height: 40rpx;
          border-radius: 50%;
          margin-right: 12rpx;
        }

        &:last-child {
          border-bottom: none;
        }

        text:first-child {
          color: #666;
          font-size: 26rpx;
        }

        text:last-child {
          font-size: 26rpx;
        }

        .status-pass {
          color: #0086FF;
        }

        .status-reject {
          color: #fb4736;
        }

        .status-pending {
          color: #999;
        }

        &.reject-reason {
          background: #FFF0F0;
          border-radius: 8rpx;
          padding: 16rpx;
          margin: 10rpx 0;

          .reason-text {
            color: #fb4736;
            flex: 1;
            margin-left: 20rpx;
            text-align: right;
          }
        }
      }
    }

    .popup-content-item-footer {
      display: flex;
      justify-content: flex-end;
      margin-top: 20rpx;
      padding-top: 20rpx;
      border-top: 2rpx solid #f5f5f5;

      .btn-disabled {
        background: #999 !important;
        opacity: 0.6;
      }

      :deep(.uv-button) {
        // margin-left: 16rpx;
        min-width: 120rpx;
      }

      :deep(.uv-button--small) {
        padding: 8rpx 20rpx;
        height: 56rpx;
        line-height: 40rpx;
        font-size: 26rpx;
      }
    }
  }
}

.audit-popup {
  height: 100%;
  display: flex;
  flex-direction: column;

  &-header {
    padding: 30rpx;
    border-bottom: 2rpx solid #eee;

    .title {
      font-size: 32rpx;
      font-weight: bold;
      color: #333;
    }
  }

  &-content {
    flex: 1;
    padding: 30rpx;
    overflow-y: auto;

    .audit-info {
      margin-bottom: 30rpx;

      .info-item {
        display: flex;
        align-items: center;
        margin-bottom: 20rpx;

        &:last-child {
          margin-bottom: 0;
        }

        .avatar {
          width: 40rpx;
          height: 40rpx;
          border-radius: 50%;
          margin-right: 12rpx;
        }

        .info-label {
          width: 140rpx;
          font-size: 28rpx;
          color: #666;
        }

        .info-value {
          flex: 1;
          font-size: 28rpx;
          color: #333;
          font-weight: 500;
        }
      }
    }

    .divider {
      height: 2rpx;
      background: #eee;
      margin: 30rpx 0;
    }

    .form-item {
      margin-bottom: 30rpx;

      .label {
        display: block;
        margin-bottom: 20rpx;
        font-size: 28rpx;
        color: #333;
      }

      .result-text {
        margin-left: 20rpx;
        font-size: 28rpx;
      }
    }
  }

  &-footer {
    padding: 20rpx 30rpx;
    border-top: 2rpx solid #eee;
    display: flex;
    justify-content: flex-end;
    gap: 20rpx;
  }
}

.stats-header {
  margin: 20rpx;
  padding: 24rpx;
  background: #FFFFFF;
  border-radius: 16rpx;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 20rpx;
  box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);

  .stats-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 16rpx 0;

    .icon-wrapper {
      width: 64rpx;
      height: 64rpx;
      border-radius: 32rpx;
      display: flex;
      align-items: center;
      justify-content: center;
      margin-bottom: 12rpx;

      .iconfont {
        font-size: 32rpx;
        color: #FFFFFF;
      }

      &.blue {
        background: $uni-gradient-primary;
      }

      &.green {
        background: $uni-gradient-primary;
      }

      &.purple {
        background: $uni-gradient-primary;
      }

      &.red {
        background: $uni-gradient-primary;
      }
    }

    .number {
      font-size: 36rpx;
      font-weight: 600;
      margin-bottom: 8rpx;
    }

    .label {
      font-size: 24rpx;
      color: #666;
    }
  }
}

.item-list-item {
  .sub-info {
    display: flex;
    align-items: center;
    gap: 12rpx;
    color: #666;
    font-size: 24rpx;

    .divider {
      color: #EBEDF0;
    }
  }

  &.highlight {
    background: #E6F7FF;
    border: 2rpx solid #91D5FF;
  }
}

.search-box {
  padding: 16rpx;
  background: #FFFFFF;
  margin-bottom: 16rpx;

  .search-input {
    position: relative;
    display: flex;
    align-items: center;
    background: #F5F6F8;
    border-radius: 28rpx;
    padding: 0 20rpx;
    height: 56rpx;

    .iconfont {
      font-size: 28rpx;
      color: #999;
      margin-right: 8rpx;
    }

    input {
      flex: 1;
      font-size: 24rpx;
      color: #333;
    }

    .clear-btn {
      width: 36rpx;
      height: 36rpx;
      line-height: 36rpx;
      text-align: center;
      font-size: 28rpx;
      color: #999;
      background: #E5E6EB;
      border-radius: 50%;
    }
  }

  .search-count {
    font-size: 22rpx;
    color: #666;
    margin-top: 8rpx;
    padding-left: 20rpx;
  }
}

.student-list {
  height: calc(100vh - 200rpx); // 调整高度以适应新的选项卡
  overflow-y: auto;
}

.search-nav {
  position: fixed;
  bottom: 40rpx;
  left: 50%;
  transform: translateX(-50%);
  background: rgba(0, 0, 0, 0.7);
  border-radius: 40rpx;
  padding: 16rpx 24rpx;
  z-index: 100;

  .nav-controls {
    display: flex;
    align-items: center;
    gap: 20rpx;

    .nav-btn {
      color: #fff;
      font-size: 26rpx;
      padding: 8rpx 20rpx;
      background: rgba(255, 255, 255, 0.2);
      border-radius: 24rpx;
    }

    .result-count {
      color: #fff;
      font-size: 24rpx;
    }
  }
}

.load-more,
.no-more {
  padding: 30rpx;
  text-align: center;
  color: #999;
  font-size: 24rpx;
  display: flex;
  align-items: center;
  justify-content: center;

  .uv-loading-icon {
    margin-right: 12rpx;
  }
}

.no-more {
  color: #999;
  padding: 30rpx;
}

.uv-tabs {
  position: relative;
  overflow: hidden;
  
  &__wrapper {
    white-space: nowrap;
    position: relative;
    display: flex;
    overflow-x: scroll;
    
    &::-webkit-scrollbar {
      display: none;
    }
  }
}

.item-list-item-center {
  padding: 16rpx;

  .score-info {
    background: #F8F9FC;
    border-radius: 12rpx;
    padding: 20rpx;
    margin-bottom: 16rpx;

    .score-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 20rpx;
      padding-bottom: 16rpx;
      border-bottom: 2rpx solid rgba(0, 0, 0, 0.05);

      .score-title {
        font-size: 30rpx;
        font-weight: 600;
        color: #333;
        position: relative;
        padding-left: 16rpx;

        &::before {
          content: '';
          position: absolute;
          left: 0;
          top: 50%;
          transform: translateY(-50%);
          width: 6rpx;
          height: 24rpx;
          background: #0086FF;
          border-radius: 3rpx;
        }
      }

      .exam-info {
        display: flex;
        flex-direction: column;
        align-items: flex-end;
        gap: 4rpx;

        .exam-count {
          font-size: 24rpx;
          color: #666;
        }

        .last-time {
          font-size: 22rpx;
          color: #999;
        }
      }
    }

    .score-stats {
      display: flex;
      gap: 20rpx;
      margin-bottom: 20rpx;

      .score-item {
        flex: 1;
        display: flex;
        align-items: center;
        background: #fff;
        padding: 16rpx;
        border-radius: 8rpx;
        box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);

        &.max-score {
          .score-icon {
            background: rgba(0, 134, 255, 0.1);
            color: #0086FF;
          }
        }

        &.min-score {
          .score-icon {
            background: rgba(251, 71, 54, 0.1);
            color: #fb4736;
          }
        }

        .score-icon {
          width: 48rpx;
          height: 48rpx;
          border-radius: 24rpx;
          display: flex;
          align-items: center;
          justify-content: center;
          margin-right: 16rpx;

          .iconfont {
            font-size: 24rpx;
          }
        }

        .score-content {
          flex: 1;

          .score-label {
            display: block;
            font-size: 24rpx;
            color: #666;
            margin-bottom: 4rpx;
          }

          .score-value {
            font-size: 32rpx;
            color: #333;
            font-weight: 600;
          }
        }
      }
    }

    .score-list {
      .list-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 12rpx;

        .list-title {
          font-size: 26rpx;
          color: #333;
          font-weight: 500;
        }

        .list-count {
          font-size: 22rpx;
          color: #999;
        }
      }

      .score-tags {
        display: flex;
        flex-wrap: wrap;
        gap: 12rpx;

        .score-tag {
          background: #fff;
          color: #333;
          padding: 6rpx 20rpx;
          border-radius: 24rpx;
          font-size: 24rpx;
          border: 2rpx solid rgba(0, 0, 0, 0.05);
          box-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.02);
        }
      }
    }
  }
}

.training-progress-list {
  margin-top: 12rpx;
  display: flex;
  flex-direction: column;
  gap: 8rpx;
}
.training-progress-row {
  display: flex;
  gap: 8rpx;
}
.training-progress-item {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  background: #fff;
  border-radius: 24rpx;
  padding: 8rpx 12rpx;
  box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.02);
  font-size: 24rpx;
  margin-bottom: 0;
  .project-title {
    color: #333;
    font-weight: 500;
    margin-bottom: 6rpx;
    font-size: 24rpx;
    width: 100%;
    word-break: break-all;
  }
  .status-capsule-row {
    width: 100%;
    display: flex;
    justify-content: flex-start;
  }
  .status-capsule {
    padding: 2rpx 12rpx;
    border-radius: 16rpx;
    font-size: 22rpx;
    font-weight: 500;
    background: #F5F6F8;
    &.status-pass {
      color: #0086FF;
      background: #E6F7FF;
      border: 2rpx solid #91D5FF;
    }
    &.status-reject {
      color: #fb4736;
      background: #FFF0F0;
      border: 2rpx solid #fb4736;
    }
    &.status-pending {
      color: #999;
      background: #F5F6F8;
      border: 2rpx solid #eee;
    }
  }
}
</style>